/*
 * ContainerDelegate.cpp  0.4.0 / Nov 17, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "ContainerDelegate.h"

// ContainerDelegate :: Protected Constructors. --------------------------------

/*!
 * \brief Constructs new ContainerDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj the Container java object
 * \param widget the widget
 */
ContainerDelegate::ContainerDelegate(JNIEnv *env, jobject obj, QWidget *widget)
  : ComponentDelegate(env, obj, widget)
{
  connectQueued(SIGNAL(validateSignal()), SLOT(validateSlot()));
}

/*!
 * \brief Constructs new ContainerDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj the Container java object
 */
ContainerDelegate::ContainerDelegate(JNIEnv *env, jobject obj)
  : ComponentDelegate(env, obj)
{
  connectQueued(SIGNAL(validateSignal()), SLOT(validateSlot()));
}

// ContainerDelegate :: Native Calls. ------------------------------------------

/*!
 * \brief Inserts child.
 *
 * \param env the JNIEnv pointer
 * \param childDelegate the child pointer
 * \param index the menu item index
 */
void ContainerDelegate::insertChild(JNIEnv *env, jlong childDelegate, jint index)
{
  Q_UNUSED(index);
  Q_ASSERT(env);
  SWING_REENTRANT(insertChild, SWING_ENV_ARG, JLONG_ARG(childDelegate),
                  JINT_ARG(index))
  ComponentDelegate *childComponentDelegate = COMPONENT_CAST(childDelegate);
  QWidget *childWidget = childComponentDelegate->qWidget();
  QRect oldGeometry = childWidget->geometry();
  setEventFilterEnabled(false);
  childComponentDelegate->setEventFilterEnabled(false);
  childWidget->setParent(qWidget());
  childComponentDelegate->setParentDelegate(this);
  if (oldGeometry != childWidget->geometry()) {
    childWidget->setGeometry(oldGeometry);
  }
  childComponentDelegate->setEventFilterEnabled(true);
  setEventFilterEnabled(true);
  if (qWidget()->isVisible()) {
    childWidget->setVisible(true);
  }
}

/*!
 * \brief Removes child.
 *
 * \param env the JNIEnv pointer
 * \param childDelegate the child pointer
 */
void ContainerDelegate::removeChild(JNIEnv *env, jlong childDelegate)
{
  Q_ASSERT(env);
  SWING_REENTRANT(removeChild, SWING_ENV_ARG, JLONG_ARG(childDelegate))
  ComponentDelegate *childComponentDelegate = COMPONENT_CAST(childDelegate);
  QWidget *childWidget = childComponentDelegate->qWidget();
  QRect oldGeometry = childWidget->geometry();
  setEventFilterEnabled(false);
  childWidget->setParent(0);
  childComponentDelegate->setParentDelegate(0);
  if (oldGeometry != childWidget->geometry()) {
    childWidget->setGeometry(oldGeometry);
  }
  setEventFilterEnabled(true);
}

/*!
 * \brief Request for validation.
 *
 * \param env the JNIEnv pointer
 */
void ContainerDelegate::validate(JNIEnv *env)
{
  Q_UNUSED(env);
  emit validateSignal();
}

// ContainerDelegate :: Static Native Calls. -----------------------------------

/*!
 * \brief Initializes ContainerDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param cls the Container java class
 *
 * \exception FatalError if failed
 */
void ContainerDelegate::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT(!sm_validateMID);
  if (!INIT_MID(validate, cls, "()V")) {
    FATAL_LOGGED_ERROR("ContainerDelegate initialization failed");
  }
}

/*!
 * \brief Returns new instance of the delegate object
 *
 * \param env the JNIEnv pointer
 * \param obj the Swing object
 * 
 * \return new instance of the delegate object
 */
jlong ContainerDelegate::newInstance(JNIEnv *env, jobject obj)
{
  if (JNISwingWrapper::isSwingThread(env)) {
    return reinterpret_cast<jlong>(new ContainerDelegate(env, obj));
  }
  return SwingUtilitiesDelegate::invokeLongAndWait(env, obj, createMID());
}

// ContainerDelegate :: Protected Member Function. -----------------------------

/*!
 * \brief validates the container
 */
void ContainerDelegate::validateSlot()
{
  jniObject()->callVoidMethod(sm_validateMID);
}

// ContainerDelegate :: Private Static Data Member. ----------------------------

jmethodID ContainerDelegate::sm_validateMID = 0;
